using Kopernikus.Collections.Generic;
using Kopernikus.Parsing.Tests.TestUtility;
using NUnit.Framework;

namespace Kopernikus.Parsing.Tests
{
    [TestFixture]
    public class TestFirstAndFollow : TestGrammarBase
    {
        // http://marvin.cs.uidaho.edu/~heckendo/CS445S07/firstfollow.txt
        private readonly string Grammar1 = @"
E E A T
E T
T T M F
T F
F ( E )
F num
A +
A -
M *
M /
";


        private static void AssertFirstForTerminals(IGrammar grammar)
        {
            foreach (Symbol s in grammar.SymbolSets.TerminalSymbols)
            {
                Set<Symbol> set = new Set<Symbol>();
                set.Add(s);
                Assert.AreEqual(set, grammar.SymbolSets.GetFirst(s));
            }
        }

        private static void AssertFirstSet(IGrammar grammar, string symbol, params string[] firstSetMembers)
        {
            Assert.AreEqual(
                MakeSymbolSet(firstSetMembers),
                grammar.SymbolSets.GetFirst(new Symbol(symbol)));
        }

        [Test]
        public void Test()
        {
            IGrammar grammar = ParseGrammar(Grammar1);

            AssertFirstForTerminals(grammar);

            AssertFirstSet(grammar, "E", "(", "num");
            AssertFirstSet(grammar, "T", "(", "num");
            AssertFirstSet(grammar, "F", "(", "num");
            AssertFirstSet(grammar, "A", "+", "-");
            AssertFirstSet(grammar, "M", "*", "/");
        }
    }
}